package com.honor.games.wg.services;

import static com.google.common.base.Preconditions.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.google.common.eventbus.EventBus;
import com.honor.games.wg.config.ApplicationConfiguration;
import com.honor.games.wg.entities.WGUnit;
import com.honor.games.wg.entities.WGUnitType;
import com.honor.games.wg.graphics.actors.WGActorType;
import com.honor.games.wg.graphics.actors.WGBoardActor;
import com.honor.games.wg.graphics.actors.WGUnitActor;
import com.honor.games.wg.graphics.actors.WGUnitClickListener;

@Service
public class WGGraphicsServices {

	private static Logger logger = LoggerFactory.getLogger(WGGraphicsServices.class);

	@Autowired
	private WGMathServices mathServices;
	
	@Autowired
	private ApplicationConfiguration config;

	@Autowired
	private EventBus eventBus;

	private WGBoardActor boardActor;
	private List<WGUnitActor> unitActors = new ArrayList<WGUnitActor>();
	private Map<String, String> unitActorMap = new HashMap<String, String>();

	private Map<WGUnitType, Texture> texturesPerUnitType;
	private Texture unitSelectionTexture;

	
	private Stage stage;
	private boolean stageSet = false;

	public Stage getStage() {
		return stage;
	}

	public void setStage(Stage stage) {
		this.stage = stage;
		stageSet = true;
	}

	public void addUnit(WGUnit unit, final float locationX, final float locationY) {

		checkArgument(stageSet, "The stage must be set before adding units");
		checkNotNull(unit);

		logger.trace("Add unit - START ({}, {})", locationX, locationY);

		WGUnitActor actor = new WGUnitActor("unit", WGActorType.UNIT, unit, texturesPerUnitType.get(unit.getUnitType()),
				unitSelectionTexture, locationX, locationY, config.getUnitSizeWidth(), config.getUnitSizeHeight());
		actor.addListener(new WGUnitClickListener(eventBus, actor, unit));
		stage.addActor(actor);

		unitActorMap.put(unit.getId(), actor.getId());
		unitActors.add(actor);
		logger.trace("Adding unit {} corresponding to actor {}", unit.getId(), actor.getId());

		logger.trace("Add unit - STOP ({}, {})", locationX, locationY);
	}

	public void setTextures(Map<WGUnitType, Texture> texturesPerUnitType, Texture unitSelectionTexture) {
		this.texturesPerUnitType = texturesPerUnitType;
		this.unitSelectionTexture = unitSelectionTexture;
	}
	
	public void selectTile(int tileX, int tileY) {
		logger.trace("Select tile - START");
		Vector2 realCoordinates = mathServices.calculateRealCoordinates(tileX, tileY);
		boardActor.setSelectedTile(realCoordinates.x, realCoordinates.y);
		logger.trace("Select tile - STOP");
	}
	
	public void unselectTile() {
		logger.trace("Unselect tile - START");
		boardActor.unselectTile();
		logger.trace("Unselect tile - STOP");
	}

	public WGBoardActor getBoardActor() {
		return boardActor;
	}

	public void setBoardActor(WGBoardActor boardActor) {
		this.boardActor = boardActor;
	}
}
